package com.cloud.freeflow.api.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.freeflow.api.entity.BizType;
import com.cloud.freeflow.api.entity.ProcDef;
import com.cloud.freeflow.api.mapper.BizTypeMapper;
import com.cloud.freeflow.api.mapper.ProcDefMapper;
import com.cloud.freeflow.api.service.ProcDefService;
import com.cloud.freeflow.common.exception.BizException;
import com.cloud.freeflow.common.result.QkTreeNode;
import com.cloud.freeflow.common.utils.SessionHelper;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class ProcDefServiceImpl implements ProcDefService {

	@Autowired
	private ProcDefMapper procDefMapper;

	@Autowired
	private BizTypeMapper bizTypeMapper;

	@Override
	public List<QkTreeNode> listProcDefTree(int bizId) {
		Example procDefExample = new Example(ProcDef.class);
		Example.Criteria criteria = procDefExample.createCriteria();
		if (bizId > 0) {
			criteria.andEqualTo("bizId", bizId);
		}
		criteria.andEqualTo("deleteFlag", 0);
		procDefExample.orderBy("bizId").asc();
		procDefExample.orderBy("procDefId").asc();
		List<ProcDef> defs = procDefMapper.selectByExample(procDefExample);
		List<QkTreeNode> procBizs = new ArrayList<QkTreeNode>();
		List<Long> bizCodes = new ArrayList<Long>();
		for (ProcDef def : defs) {
			Long bizCode = def.getBizId();
			if (!bizCodes.contains(bizCode)) {
				QkTreeNode node = new QkTreeNode(def.getBizId(), def.getBizName());
				node.setExpanded(true);
				node.setSelectable(false);
				node.setExpandedIcon("fa fa-folder-open");
				node.setCollapsedIcon("fa fa-folder");
				node.getData().put("type", 0);
				procBizs.add(node);
				bizCodes.add(bizCode);
			}
		}
		// 封装业务流程节点
		for (QkTreeNode rootNode : procBizs) {
			for (ProcDef def : defs) {
				if (rootNode.getId().equals(def.getBizId() + "")) {
					QkTreeNode node = new QkTreeNode();
					node.setId(def.getProcDefId() + "");
					node.setLabel(def.getProcDefName());
					node.setSelectable(true);
					node.setLeaf(true);
					node.setIcon("fa fa-share-alt");
					node.getData().put("type", 1);
					node.getData().put("id", def.getProcDefId());
					rootNode.getChildren().add(node);
				}
			}
		}
		return procBizs;
	}

	@Override
	public ProcDef showDetail(long id) {
		return procDefMapper.selectByPrimaryKey(id);
	}

	@Override
	public long saveUpdateProcDef(ProcDef def) throws BizException {
		Long procDefId = def.getProcDefId();
		if (null != procDefId && procDefId > 0) {
			if (procDefMapper.checkProcNameExitsUpdate(def.getProcDefName(), def.getBizId(), procDefId) > 0)
				throw new BizException(500, "名称为：" + def.getProcDefName() + "已经存在");
			procDefMapper.updateByPrimaryKeySelective(def);
		} else {
			if (def.getBizId() == null || def.getBizId().intValue() == 0) {
				// 业务类型不存在，则新增业务类型
				Example example = new Example(BizType.class);
				Example.Criteria criteria = example.createCriteria();
				criteria.andEqualTo("bizName", def.getBizName());
				List<BizType> types = bizTypeMapper.selectByExample(example);
				if (types == null || types.size() == 0) {
					Long bizId = bizTypeMapper.getMaxBizId();
					BizType bizType = new BizType();
					bizType.setBizId(bizId+1);
					bizType.setBizName(def.getBizName());
					bizType.setDeleteFlag(0);
					bizType.setCustomFlag(0);
					bizType.setCreateTime(new Date());
					bizType.setCreateUser(SessionHelper.get().getHumanName());
					bizTypeMapper.insert(bizType);
					def.setBizId(bizType.getBizId());
				} else {
					throw new BizException(500, "名称为：" + def.getBizName() + "的业务已经存在");
				}
			}
			def.setProcDefId(procDefId);
			def.setCreateTime(new Date());
			def.setCreateUser(SessionHelper.get().getHumanName());
			def.setDeleteFlag(0);
			procDefMapper.insert(def);
			procDefId = def.getProcDefId();
		}
		return procDefId;
	}

	@Override
	public long deleteProcDef(long id) {
		ProcDef procDef = new ProcDef();
		procDef.setProcDefId(id);
		procDef.setDeleteFlag(1);
		procDefMapper.updateByPrimaryKeySelective(procDef);
		return id;
	}

	@Override
	public List<ProcDef> listProcDefs(Long bizId) {
		Example example = new Example(ProcDef.class);
		Example.Criteria criteria = example.createCriteria();
		if (null != bizId && bizId > 0) {
			criteria.andEqualTo("bizId", bizId);
		}
		criteria.andEqualTo("deleteFlag", 0);
		return procDefMapper.selectByExample(example);
	}

}
